﻿namespace Webinator.Toolboxes
{
    using System.Diagnostics.CodeAnalysis;
    using System.Threading;
    using Webinator.Impls;
    using Webinator.Interfaces;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed. Suppression is OK here.")]
    public class AjaxToolbox : IAjax
    {
        private readonly IJavascript _javascript;

        private readonly IWebManager _webManager;

        public AjaxToolbox(IJavascript javascriptToolbox, IWebManager webManager)
        {
            _javascript = javascriptToolbox;
            _webManager = webManager;
        }

        public void BeginListeningForAjax()
        {
            _javascript.InjectJquery();

            if (_webManager.GetNodeCount(LocateBy.Xpath("//div[@id='WebinatorAjaxDetected']")).Equals(0))
            {
                string ajaxDetected =
                    @"$(""body"").append(""<div id='WebinatorAjaxDetected' style='display:none;'></div>"");" +
                    string.Format(Scripts.Message, "Ajax detected...", 2000);

                string ajaxCompleted =
                    @"$('#WebinatorAjaxDetected').remove(); $(""body"").append(""<div id='WebinatorAjaxFinished' style='display:none;'></div>"");" +
                    string.Format(Scripts.Message, "Ajax completed...", 2000);

                string js = string.Format(
                        @"$(document).bind(""ajaxStart"", function() {{{0}}}).bind(""ajaxStop"", function() {{{1}}});", ajaxDetected, ajaxCompleted);

                _javascript.RunJavaScript(js);
            }
        }

        public bool AjaxIsRunning()
        {
            int i = _webManager.GetNodeCount(LocateBy.Xpath("//div[@id='WebinatorAjaxDetected']"));
            if (i == 0)
            {
                i = _webManager.GetNodeCount(LocateBy.Xpath("//div[@id='WebinatorAjaxFinished']"));
            }

            return i > 0;
        }

        public void WaitForAjaxToComplete(int timeoutInMilliseconds = 10000)
        {
            int i = 0;
            const int PollRate = 250;
            int retries = timeoutInMilliseconds / PollRate;
            do
            {
                i++;
                var ajaxFinished = _webManager.GetNodeCount(LocateBy.Xpath("//div[@id='WebinatorAjaxFinished']")) > 0;
                if (ajaxFinished)
                {
                    return;
                }

                Thread.Sleep(PollRate);
            } 
            while (i < retries);
        }
        
        public void StopListeningForAjax()
        {
            _javascript.InjectJquery();
            if (AjaxIsRunning())
            {
                _javascript.RunJavaScript("$('#WebinatorAjaxFinished').remove(); $(document).unbind('ajaxStart').unbind('ajaxStop');");
            }
        }
    }
}
